在科研论文写作中,经常会遇到画色温图,3D图。此时一般输入的数据量比较大,导致在Latex中使用Tikz画图时出现内存不足的情况。常常报错如下:
1 | ! TeX capacity exceeded, sorry [main memory size=5000000]. |
参考pgfplots手册中的第六章,我们有以下解决方案:
- 使用LuaTex进行编译
有些版本不含LuaTex - 对输入数据采样降低数据量
不是从本质上解决问题,降低了精度 - 使用其它软件画图,e.g., MATLAB
- 增大LaTex的编译内存
本文主要介绍如何在MacOS系统中Texlive平台下,克服内LaTex内存限制。关于在Linux和MiKTEX环境下,pgfplots手册已给了说明,这里不再赘述。
解决办法:在Texlive安装目录中找到texmf.cnf文件并编辑:
其安装目录在:
/usr/local/texlive/2018/texmf-dist/web2c/texmf.cnf
注意:/usr/local/texlive/2018/texmf.cnf也有相同的文件,编辑这个文件无法解决问题
其内容修改如下:
注意:修改的内存大小不能超过实际内存大小,我的是8G.
最后,打开终端进入安装目录下,执行
1 | sudo texhash |
若发生文件不可写的情况,可以使用chmod 777
来更改文件读写权限。
下面,我们通过实例来验证:
数据产生
我们使用Matlab的peaks函数来产生peaks.dat文件用于tikz画图的输入数据。其代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26clear all
clc
close all
lambda_total=2;% the sum of Z
[X,Y,Z] = peaks(100);
Z(Z<0)=0;
Z=Z/sum(sum(Z))*lambda_total;
x_temp=repmat(1:100,100,1);% X-axis
x_temp=x_temp(:);
y_temp=repmat(1:100,1,100);%Y-axis
xyz=['x y z'];
dlmwrite('peaks.dat',xyz,'delimiter',' ');
for x_ind=1:size(Z,1)
for y_ind=1:size(Z,2)
% for one point (x,y,z), we use 4 coordinates (x,y,z) (x,y+1,z) (x+1,y+1,z) (x+1,y,z) to form a patch
xyz=[x_ind y_ind Z(x_ind, y_ind);x_ind y_ind+1 Z(x_ind, y_ind);x_ind+1 y_ind+1 Z(x_ind, y_ind);x_ind+1 y_ind Z(x_ind, y_ind)];
if(x_ind==1&&y_ind==1)
dlmwrite('peaks.dat',xyz,'delimiter',' ','-append','roffset',0);
else
dlmwrite('peaks.dat',xyz,'delimiter',' ','-append','roffset',1);
end
end
end在Tikz中画图
本文使用了patch来画图,也可以改用surf, mesh等。完整latex源代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21\documentclass{standalone}
\def\pgfsysdriver{pgfsys-dvipdfmx.def}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{width=7cm,compat=1.14}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
colorbar,
xmin=1,xmax=101,
ymin=1,ymax=101,
xlabel={X-axis (m)},
ylabel={Y-axis (m)},
]
\addplot [patch,patch type=rectangle]
table [point meta=\thisrow{z}]
{peaks.dat };
\end{axis}
\end{tikzpicture}
\end{document}画图效果如下: